home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 April: Mac OS SDK / Dev.CD Apr 96 SDK / Dev.CD Apr 96 SDK1.toast / Development Kits (Disc 1) / OpenDoc / Sample Code / CALib & You… / Source / CALib / Implementation / UI / CADisptch.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1995-12-07  |  13.6 KB  |  632 lines  |  [TEXT/MPS ]

  1. /*
  2.     File:            CADisptch.cpp
  3.  
  4.     Contains:        CADispatcher implementation
  5.  
  6.     Written by:    Rick Badertscher
  7.  
  8.     Copyright:    © 1993-95 by Apple Computer, Inc., all rights reserved.
  9.  
  10.     Change History (most recent first):
  11.  
  12.          <0>      8/2/95    RB        Created
  13.  
  14.  
  15.     To Do:
  16. */
  17.  
  18. #ifndef SOM_ODWindow_xh
  19. #include "Window.xh"
  20. #endif
  21.  
  22. #ifndef _CADISPTCH_
  23. #include "CADisptch.h"
  24. #endif
  25.  
  26. #ifndef _CAFRMUTL_
  27. #include "CAFrmUtl.h"
  28. #endif
  29.  
  30. #ifndef SOM_ODSession_xh
  31. #include <ODSessn.xh>
  32. #endif
  33.  
  34. #ifndef SOM_Module_OpenDoc_StdTypes_defined
  35. #include <StdTypes.xh>
  36. #endif
  37.  
  38. #ifndef SOM_Module_OpenDoc_StdProps_defined
  39. #include <StdProps.xh>
  40. #endif
  41.  
  42. #ifndef SOM_Module_OpenDoc_StdDefs_defined
  43. #include <StdDefs.xh>
  44. #endif
  45.  
  46. #ifndef _ODUTILS_
  47. #include <ODUtils.h>
  48. #endif
  49.  
  50. #ifndef _ORDCOLL_
  51. #include <OrdColl.h>
  52. #endif
  53.  
  54. #ifndef SOM_ODWindowState_xh
  55. #include <WinStat.xh>
  56. #endif
  57.  
  58. #ifndef SOM_ODMenuBar_xh
  59. #include <MenuBar.xh>
  60. #endif
  61.  
  62. #ifndef SOM_Module_OpenDoc_Commands_defined
  63. #include <CmdDefs.xh>
  64. #endif
  65.  
  66. #ifndef SOM_ODDispatcher_xh
  67. #include <Disptch.xh>
  68. #endif
  69.  
  70. #ifndef SOM_ODFoci_xh
  71. #include <Foci.xh>
  72. #endif
  73.  
  74. #ifndef SOM_ODTransform_xh
  75. #include <Trnsform.xh>
  76. #endif
  77.  
  78. #ifndef SOM_ODFacet_xh
  79. #include <Facet.xh>
  80. #endif
  81.  
  82. #ifndef SOM_ODShape_xh
  83. #include <Shape.xh>
  84. #endif
  85.  
  86. #ifndef _CASESSN_
  87. #include "CASessn.h"
  88. #endif
  89.  
  90. #ifndef _CAUTIL_
  91. #include "CAUtil.h"
  92. #endif
  93.  
  94. #ifndef _CADEBUG_
  95. #include "CADebug.h"
  96. #endif
  97.  
  98. #ifndef _TEMPOBJ_
  99. #include <TempObj.h>
  100. #endif
  101.  
  102.  
  103. // For window resizing
  104. #define kMinWindowWidth  192
  105. #define kMinWindowHeight 64
  106. #define kMaxWindowWidth  16384
  107. #define kMaxWindowHeight 16384
  108.  
  109.  
  110. #pragma segment CALib
  111.  
  112. //-------------------------------------------------------------------------
  113.  
  114. static Boolean        FilterKeyEvent (EventRecord* event);
  115. static Boolean        IsCADocWindow (ODWindow* window);
  116.  
  117.  
  118. //-------------------------------------------------------------------------------------
  119.  
  120. CADispatcher::CADispatcher()
  121. {
  122.  
  123.     fDispatcher     = kODNULL;
  124.     fWindowState    = kODNULL;
  125.     fEV                = kODNULL;
  126.     
  127. }
  128.  
  129. //-------------------------------------------------------------------------------------
  130.  
  131. CADispatcher::~CADispatcher()
  132. {
  133.  
  134. }
  135.  
  136.  
  137. //-------------------------------------------------------------------------------------
  138.  
  139. void CADispatcher::Initialize(ODSession* session)
  140. {
  141.  
  142.     fEV = somGetGlobalEnvironment();
  143.     fDispatcher = session->GetDispatcher(fEV);
  144.     fWindowState = session->GetWindowState(fEV);
  145.     
  146. }
  147.  
  148.  
  149. //-------------------------------------------------------------------------------------
  150. // CADispatcher::DispatchEvent
  151. //-------------------------------------------------------------------------------------
  152.  
  153. Boolean CADispatcher::DispatchEvent(ODEventData* event, CAEventInfo* eventInfo)
  154. {
  155.     Boolean            result            = kODFalse;
  156.     ODSShort         eventType;
  157.  
  158.     eventType = event->what;
  159.     
  160.     switch (eventType)
  161.     {
  162.         case diskEvt:
  163.         case activateEvt:
  164.         case kHighLevelEvent:
  165.             return (kODFalse);
  166.             break;
  167.         
  168.         case mouseDown:
  169.         case mouseUp:
  170.         
  171.             return (this->DispatchMouseEvent (event, eventInfo));
  172.             break;
  173.             
  174.         case updateEvt:
  175.  
  176.             return (this->DispatchUpdateEvent (event));
  177.             //return (false);
  178.             break;
  179.  
  180.         case keyDown:
  181.         
  182.             if (FilterKeyEvent (event)) return (kODFalse);
  183.             break;
  184.             
  185.         case osEvt:
  186.         
  187.             return (this->DispatchOSEvent (event, eventInfo));
  188.             break;
  189.             
  190.         case nullEvent:
  191.         case autoKey:
  192.         case keyUp:
  193.         
  194.             break;
  195.     
  196.     }
  197.         
  198.     // Dispatch the event to OpenDoc
  199.     
  200.     result = fDispatcher->Dispatch( fEV, (ODEventData*) event);
  201.             
  202.     switch (eventType)
  203.     {
  204.         case nullEvent:
  205.             result = false;
  206.             break;
  207.             
  208.         case osEvt:
  209.             result = false;
  210.             break;
  211.     
  212.     }
  213.  
  214.     return result;
  215.  
  216. }
  217.  
  218. //-------------------------------------------------------------------------------------
  219. // CADispatcher::DispatchMenuEvent
  220. //-------------------------------------------------------------------------------------
  221.  
  222. Boolean CADispatcher::DispatchMenuEvent(ODEventData* event)
  223. {
  224.     Boolean        result = false;
  225.     
  226.     if (!(result = fDispatcher->Dispatch(fEV,event)))
  227.         result = gCASession->HandleMenuCommand(event->message, event);
  228.         
  229.     return (result);
  230.     
  231. }
  232.  
  233. //-------------------------------------------------------------------------------------
  234. // CADispatcher::DispatchOSEvent
  235. //-------------------------------------------------------------------------------------
  236.  
  237. Boolean    CADispatcher::DispatchOSEvent( ODEventData* event, CAEventInfo* eventInfo)
  238. {
  239.     Boolean            result            = false;
  240.     Boolean            isMouseMoved     = false;
  241.     Boolean            isCAWindow        = false;
  242.     WindowPtr        window;
  243.  
  244.     isMouseMoved = (((event->message >> 24) & 0x0FF) == mouseMovedMessage);
  245.     
  246.     if (isMouseMoved)
  247.     {
  248.             
  249.         FindWindow(event->where, &window);
  250.  
  251.         if (window)
  252.         {
  253.             TempODWindow tempWindow = fWindowState->AcquireODWindow(fEV, window);
  254.             isCAWindow = IsCADocWindow (tempWindow);
  255.         }
  256.  
  257.     }
  258.  
  259.     result = fDispatcher->Dispatch( fEV, (ODEventData*) event);
  260.     
  261.     result = false;
  262.     
  263.     if (isMouseMoved)
  264.     {
  265.         if (!isCAWindow)
  266.             result = true;
  267.     }
  268.     
  269.     return (result);
  270.                 
  271. }
  272.  
  273. //-------------------------------------------------------------------------------------
  274. // CADispatcher::DispatchUpdateEvent
  275. //-------------------------------------------------------------------------------------
  276.  
  277. Boolean CADispatcher::DispatchUpdateEvent(ODEventData* event)
  278. {
  279.  
  280.     Boolean            result            = false;
  281.     WindowPtr        theWindow;
  282.     CADocument*        docRef;
  283.  
  284.     theWindow = (WindowPtr)(event->message);
  285.     
  286.     if (theWindow && fWindowState->IsODWindow(fEV, theWindow))
  287.     {
  288.         TempODWindow tempWindow = fWindowState->AcquireODWindow(fEV, theWindow);
  289.         docRef = gCASession->FindCADocumentRefForWindow (tempWindow);
  290.     }
  291.     
  292.     if (!docRef)
  293.         result = fDispatcher->Dispatch( fEV, (ODEventData*) event);
  294.  
  295.     return (result);
  296.  
  297. }
  298.  
  299. //-------------------------------------------------------------------------------------
  300. // CADispatcher::DispatchMouseEvent
  301. //-------------------------------------------------------------------------------------
  302.  
  303. Boolean CADispatcher::DispatchMouseEvent(ODEventData* event, CAEventInfo* eventInfo)
  304. {
  305.  
  306.     CADocument*        docRef            = NULL;
  307.     Boolean            result            = kODFalse;
  308.     Boolean            isCARootWindow    = kODFalse;
  309.     ODWindow*        aODWindow        = kODNULL;
  310.     ODSShort         partCode;
  311.     ODEventInfo        odEventInfo;
  312.     EventRecord        saveEvent;    
  313.     WindowPtr        theWindow;
  314.  
  315.     saveEvent = *event;
  316.     
  317.     partCode = FindWindow( event->where, &theWindow );
  318.     
  319.     TRACE (1, "CADispatcher::DispatchMouseEvent - theWindow = %x, partCode = %d", theWindow, partCode);
  320.     
  321.     if (theWindow && (!fWindowState->IsODWindow(fEV, theWindow)))
  322.     {    
  323.         DebugStr ("\pmouse down event in non-OD window");
  324.         return (kODFalse);
  325.     }
  326.     
  327.     if (partCode == kODMDInMenuBar)
  328.         return (kODFalse);
  329.  
  330.     // Dispatch the event to OpenDoc
  331.     
  332.     result = fDispatcher->Dispatch( fEV, (ODEventData*) event);
  333.  
  334.     if (!result)
  335.     {
  336.     
  337.         ODFrame*    focusFrame            = kODNULL;
  338.         ODFrame*    frameUnderPoint        = kODNULL;;
  339.         ODFacet*    facet;
  340.         ODPoint        windowPoint;
  341.         
  342.         if (fWindowState->IsODWindow(fEV, theWindow))
  343.         {
  344.             aODWindow = fWindowState->AcquireODWindow(fEV, theWindow);
  345.             docRef = gCASession->FindCADocumentRefForWindow (aODWindow);
  346.         }
  347.         
  348.         if (aODWindow)
  349.         {
  350.         
  351.             aODWindow->GetWindowPoint (fEV, &(event->where), &windowPoint);
  352.             facet = aODWindow->GetFacetUnderPoint (fEV, &windowPoint);
  353.         
  354.             if (facet)
  355.             {
  356.                 frameUnderPoint = facet->GetFrame (fEV);
  357.                 
  358.                 TempODFrame tempFrame = gCASession->GetArbitrator()->AcquireFocusOwner(fEV,
  359.                             gCASession->GetODSession()->Tokenize(fEV, kODSelectionFocus));
  360.         
  361.                 if (tempFrame && (tempFrame == frameUnderPoint) &&
  362.                     (!tempFrame->IsRoot(fEV)))
  363.                 {
  364.                     //DebugStr ("\p CADispatcher - forcing CADispatchEvent() to return true");
  365.                     result = true;
  366.                 }
  367.             }
  368.         
  369.         }
  370.         
  371.         ODReleaseObject (fEV, aODWindow);
  372.     
  373.     }
  374.     
  375.     
  376.     if (!result && !docRef)
  377.     {
  378.         // Mouse down is in a non-CA part window
  379.         result = true;
  380.         this->HandleMouseDownInWindow(theWindow, partCode, event);
  381.     }
  382.     
  383.     // Get the stored ODEventInfo info from the proxy part
  384.     // Note: switching on the event record as modified by the OpenDoc dispatcher.
  385.     
  386.     if (result == kODFalse)
  387.     {
  388.     
  389.         switch (event->what)
  390.         {
  391.         
  392.             case kODEvtWindow:
  393.             
  394.                 *event = saveEvent;                // restore event record
  395.                 break;
  396.                 
  397.             case kODEvtMouseDownEmbedded:
  398.             case kODEvtBGMouseDownEmbedded:
  399.             case kODEvtMouseDownBorder:
  400.             case kODEvtMouseUpBorder:
  401.             case kODEvtMouseUpEmbedded:
  402.             
  403.     
  404.                 if (eventInfo && docRef)
  405.                 {
  406.                 
  407.                     GetEventInfo ((CADocumentRef) docRef, &odEventInfo);
  408.                     eventInfo->eventType = event->what;
  409.                     eventInfo->embeddedFrame = FrameRefFromFrame ((CADocumentRef) docRef, odEventInfo.embeddedFrame);
  410.                     eventInfo->embeddedVisFrame = (CAVisFrame) odEventInfo.embeddedFacet;
  411.                     eventInfo->propagated = odEventInfo.propagated;
  412.                 
  413.                 }
  414.                 
  415.                 break;
  416.                 
  417.             default:
  418.             
  419.                 break;
  420.                 
  421.     
  422.         }
  423.     
  424.     }
  425.  
  426.     return (result);
  427.     
  428. }
  429.  
  430.  
  431. //-------------------------------------------------------------------------------------
  432. // CADispatcher::HandleMouseDownInWindow
  433. //-------------------------------------------------------------------------------------
  434.  
  435. void CADispatcher::HandleMouseDownInWindow(WindowPtr pwindow, ODSShort partCode, ODEventData* event)
  436. {
  437.     switch (partCode)
  438.     {
  439.     
  440.         case kODMDInGoAway:    
  441.             this->HandleMouseDownInCloseBox(pwindow, event);            
  442.             break;
  443.     
  444.         case kODMDInDrag:        
  445.             this->HandleMouseDownInDragRegion(pwindow, event);            
  446.             break;
  447.             
  448.         case kODMDInGrow:        
  449.             this->HandleMouseDownInGrowBox(pwindow, event);            
  450.             break;
  451.                             
  452.         case kODMDInZoomIn:
  453.         case kODMDInZoomOut:    
  454.             this->HandleMouseDownInZoomBox(pwindow, partCode,event);    
  455.             break;
  456.             
  457.         case kODMDInContent:
  458.             {
  459.             ODWindow* window = fWindowState->AcquireODWindow(fEV,pwindow);
  460.             if (window != kODNULL)
  461.                 window->Select(fEV);
  462.             else
  463.                 SelectWindow(pwindow);
  464.                 
  465.             ODReleaseObject (fEV, window);
  466.             break; 
  467.             }                
  468.         default:                
  469.             break;
  470.     }
  471. }
  472.  
  473. //-------------------------------------------------------------------------------------
  474. // CADispatcher::HandleMouseDownInCloseBox
  475. //-------------------------------------------------------------------------------------
  476.  
  477. void CADispatcher::HandleMouseDownInCloseBox(WindowPtr window, ODEventData* event)
  478. {
  479.  
  480.     TempODWindow tempWindow = fWindowState->AcquireODWindow(fEV, window);
  481.     
  482.     if (TrackGoAway (window, event->where))
  483.         tempWindow->CloseAndRemove(fEV);            
  484.     else
  485.         tempWindow->Release(fEV);
  486.         
  487. }
  488.  
  489. //-------------------------------------------------------------------------------------
  490. // CADispatcher::HandleMouseDownInDragRegion
  491. //-------------------------------------------------------------------------------------
  492.  
  493. void CADispatcher::HandleMouseDownInDragRegion(WindowPtr platformWindow, ODEventData* event)
  494. {
  495.  
  496.     TempODWindow tempWindow = fWindowState->AcquireODWindow(fEV, platformWindow);
  497.     
  498.     if (tempWindow) 
  499.         tempWindow->Drag(fEV, &event->where, (Rect*)&ODQDGlobals.screenBits.bounds);
  500.     else 
  501.     {
  502.         WARN("Dragging non-ODWindow.");
  503.         DragWindow(platformWindow, event->where, &(ODQDGlobals.screenBits.bounds));
  504.     }
  505.  
  506. }
  507.  
  508. //-------------------------------------------------------------------------------------
  509. // CADispatcher::HandleMouseDownInGrowBox
  510. //-------------------------------------------------------------------------------------
  511.  
  512. void CADispatcher::HandleMouseDownInGrowBox(WindowPtr pwindow, ODEventData* event)
  513. {
  514.     ODWindow*  window = kODNULL;
  515.     if (fWindowState->IsODWindow(fEV,pwindow))
  516.         window = fWindowState->AcquireODWindow(fEV,pwindow);
  517.  
  518.     if (window == kODNULL)
  519.         return;
  520.         
  521.     if (window->IsResizable(fEV))
  522.     {
  523.         Rect growLimits; //  = ODQDGlobals.screenBits.bounds);
  524.         
  525.         ODRgnHandle contRgn = 
  526.             ((WindowRecord*)(window->GetPlatformWindow(fEV)))->contRgn;
  527.         Rect currentBounds = (**contRgn).rgnBBox;
  528.  
  529.         window->GetWindowBounds(fEV, ¤tBounds);
  530.         
  531.         growLimits.left = currentBounds.right-currentBounds.left;
  532.         if (growLimits.left > kMinWindowWidth)
  533.             growLimits.left = kMinWindowWidth;
  534.         growLimits.top = currentBounds.bottom-currentBounds.top;
  535.         if (growLimits.top > kMinWindowHeight)
  536.             growLimits.top = kMinWindowHeight;
  537.             
  538.         growLimits.right = kMaxWindowWidth;
  539.         growLimits.bottom = kMaxWindowHeight;
  540.         
  541.         ODSLong newWindowSize = GrowWindow(pwindow, event->where, &growLimits);
  542.         SizeWindow(pwindow, LoWord(newWindowSize), HiWord(newWindowSize), true);
  543.     
  544.         window->AdjustWindowShape(fEV);
  545.     
  546.         Rect r = pwindow->portRect;
  547.         r.left = r.right  - 15;
  548.         r.top  = r.bottom - 15;
  549.         RgnHandle    oldClip = nil;
  550.         GetClip(oldClip = ODNewRgn());
  551.         ClipRect(&r);
  552.         DrawGrowIcon(pwindow);
  553.         SetClip(oldClip);
  554.         DisposeRgn(oldClip);
  555.     }
  556.     ODReleaseObject(fEV, window);
  557.  
  558. }
  559.  
  560. //-------------------------------------------------------------------------------------
  561. // CADispatcher::HandleMouseDownInZoomBox
  562. //-------------------------------------------------------------------------------------
  563.  
  564. void CADispatcher::HandleMouseDownInZoomBox(WindowPtr pwindow, ODSShort partcode, ODEventData* event)
  565. {
  566.     if (TrackBox(pwindow, event->where, partcode))
  567.     {
  568.         ODWindow*  window = kODNULL;
  569.         
  570.         if (fWindowState->IsODWindow(fEV,pwindow))
  571.             window = fWindowState->AcquireODWindow(fEV,pwindow);
  572.         
  573.         GrafPtr port;
  574.         GetPort(&port);
  575.         SetPort(pwindow);
  576.         
  577.         ZoomWindow(pwindow, partcode, kODFalse);
  578.         
  579.         SetPort(port);
  580.         
  581.         if (window)
  582.             window->AdjustWindowShape(fEV);
  583.         ODReleaseObject(fEV, window);
  584.     }
  585. }
  586.  
  587.  
  588.  
  589.  
  590. //-------------------------------------------------------------------------------------
  591.  
  592. static Boolean FilterKeyEvent (EventRecord* event)
  593. {
  594.     Environment*    ev                = gCASession->GetEV();
  595.     ODArbitrator*    arbitrator        = gCASession->GetArbitrator();;
  596.     char            key;
  597.     Boolean            result = false;
  598.     
  599.     key    = (char) (event->message & charCodeMask) ;
  600.  
  601.     // if the command key was pressed
  602.     if ((event->modifiers & cmdKey) != 0)
  603.     {
  604.         // Don't dispatch this event, it will be dispatched as a menu
  605.         // event by the CA later.
  606.         result = true;
  607.     }
  608.     
  609.     TempODFrame tempFrame = arbitrator->AcquireFocusOwner (ev,
  610.                         gCASession->GetODSession()->Tokenize(ev, kODKeyFocus));
  611.     
  612.     if (tempFrame && tempFrame->IsRoot (ev))
  613.     {
  614.         result = true;
  615.     }
  616.     
  617.     return (result);
  618.  
  619. }
  620.  
  621.  
  622. static Boolean    IsCADocWindow (ODWindow* window)
  623. {
  624.     
  625.     if (gCASession->FindCADocumentRefForWindow (window))
  626.         return true;
  627.         
  628.     return false;
  629.  
  630. }
  631.  
  632.